home *** CD-ROM | disk | FTP | other *** search
- /* $Id: move.c,v 1.1.1.1 1993/06/21 11:12:00 anjo Exp $
- *
- * File move.c
- * Part of ChessBase utilities file format (CBUFF)
- * Author Anjo Anjewierden, anjo@swi.psy.uva.nl
- * Purpose Moves
- * Works with GNU CC 2.4.5
- *
- * Notice Copyright (c) 1993 Anjo Anjewierden
- *
- * History 10/06/93 (Created)
- * 13/10/93 (Last modified)
- */
-
-
- /*------------------------------------------------------------
- * Directives
- *------------------------------------------------------------*/
-
- #include "cbuff.h"
-
-
- /*------------------------------------------------------------
- * Initialisation
- *------------------------------------------------------------*/
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @node newMove
- @deftypefun Move newMove ()
- Allocates a new move and returns it.
- @end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- Move
- newMove()
- { Move me;
-
- me = alloc(sizeof(struct move));
- me->from = 0x00;
- me->to = 0x00;
- me->piece = NO_PIECE;
- me->moveEvaluation = '\0';
- me->positionEvaluation = '\0';
- me->extraEvaluation = '\0';
- me->commentLength = 0;
- me->comments = NULL;
- me->next = NULL;
- me->alternative = NULL;
-
- return me;
- }
-
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @node freeMove
- @deftypefun void freeMove (Move @var{m})
- Reclaims the memory of a move previously allocated with @code{newMove}.
- @end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- void
- freeMove(Move m)
- { if (m->next)
- freeMove(m->next);
- if (m->alternative)
- freeMove(m->alternative);
- if (m->comments)
- unalloc(m->comments);
- unalloc(m);
- }
-
-
- /*------------------------------------------------------------
- * Printing
- *------------------------------------------------------------*/
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @node diagramMoveP
- @deftypefun bool diagramMoveP (Move @var{m})
- Succeeds when the comments of the move contain an instruction to
- print a diagram. In ChessBase, a diagram is requested by entering
- @key{Control-D} as a comment for the move.
- @end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- bool
- diagramMoveP(Move m)
- { if (m->commentLength)
- { int n;
-
- for (n=0; n<m->commentLength; n++)
- { if (m->comments[n] == REQUEST_DIAGRAM)
- return TRUE;
- }
- }
- return FALSE;
- }
-
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @node containsCommentsMoveP
- @deftypefun bool containsCommentsMoveP (Move @var{m})
- Succeeds when @var{m} contains comments. The diagram indicator is
- ignored here, so when the only comment is to print a diagram this
- function fails.
- @end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- bool
- containsCommentsMoveP(Move m)
- { if (m->commentLength)
- { unsigned char *s;
-
- for (s=m->comments; *s; s++)
- { if (*s == REQUEST_DIAGRAM)
- continue;
- if (*s >= ' ') /* Printable character */
- return TRUE;
- }
- }
- return FALSE;
- }
-
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @node containsVariationsMoveP
- @deftypefun bool containsVariationsMoveP (Move @var{m})
- Succeeds when there are alternatives for move @var{m}.
- @end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- bool
- containsVariationsMoveP(Move m)
- { return (m->alternative ? TRUE : FALSE);
- }
-
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @node outputCommentsMove
- @deftypefun void outputCommentsMove (Move @var{m}, TextBuffer @var{tb}, Position @var{pos})
- Prints the comments for move @var{m} in the textbuffer @var{tb}.
- A diagram will be printed at the appropriate point, if the comment
- contains a diagram request.
- @end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- void
- outputCommentsMove(Move m, TextBuffer tb, Position pos)
- { if (m->commentLength)
- { unsigned char *s;
-
- stringTextBuffer(tb, chessSymbol(START_COMMENT));
- for (s=m->comments; *s; s++)
- { if (*s >= ' ' && *s < '\177')
- { char buf[2];
-
- buf[0] = *s;
- buf[1] = '\0';
- stringTextBuffer(tb, buf);
- continue;
- }
- if (*s == '\177')
- { stringTextBuffer(tb, chessSymbol(WITH_IDEA));
- continue;
- }
- if (*s == REQUEST_DIAGRAM)
- { stringTextBuffer(tb, chessSymbol(START_COMMENT));
- diagramPosition(pos, tb);
- stringTextBuffer(tb, chessSymbol(END_COMMENT));
- continue;
- }
- stringTextBuffer(tb, mapChessSymbol(*s));
- }
- stringTextBuffer(tb, chessSymbol(END_COMMENT));
- }
- }
-
-
- void
- outputMove(Move m, TextBuffer tb, Position pos, int algebraic)
- { switch (m->extraEvaluation) /* These are printed before move */
- { case '\000': break;
- case '\001': stringTextBuffer(tb, chessSymbol(EDITORIAL_COMMENT)); break;
- case '\002': stringTextBuffer(tb, chessSymbol(BETTER_IS)); break;
- case '\003': stringTextBuffer(tb, chessSymbol(WITH_IDEA)); break;
- case '\004': stringTextBuffer(tb, "~~"); break;
- case '\005': stringTextBuffer(tb, chessSymbol(BETTER_IS)); break;
- case '\006': stringTextBuffer(tb, chessSymbol(WORSE_IS)); break;
- default: setError(ERR_UNKNOWN_EXTRA_EVALUATION);
- }
-
- stringTextBuffer(tb, getStringMovePosition(pos, m, algebraic));
-
- switch (m->moveEvaluation)
- { case '\000': break;
- case '\001': stringTextBuffer(tb, chessSymbol(GOOD_MOVE)); break;
- case '\002': stringTextBuffer(tb, chessSymbol(BAD_MOVE)); break;
- case '\003': stringTextBuffer(tb, chessSymbol(INTERESTING_MOVE)); break;
- case '\004': stringTextBuffer(tb, chessSymbol(DUBIOUS_MOVE)); break;
- case '\005': stringTextBuffer(tb, chessSymbol(BRILLIANT_MOVE)); break;
- case '\006': stringTextBuffer(tb, chessSymbol(BLUNDER)); break;
- case '\007': stringTextBuffer(tb, chessSymbol(MATE)); break;
- case '\010': stringTextBuffer(tb, chessSymbol(TIME_TROUBLE)); break;
- case '\011': stringTextBuffer(tb, chessSymbol(DEVELOPMENT_ADVANTAGE)); break;
- default: setError(ERR_UNKNOWN_MOVE_EVALUATION);
- }
-
- switch (m->positionEvaluation)
- { case '\000': break;
- case '\001': stringTextBuffer(tb, chessSymbol(WHITE_WINNING)); break;
- case '\002': stringTextBuffer(tb, chessSymbol(WHITE_ADVANTAGE)); break;
- case '\003': stringTextBuffer(tb, chessSymbol(WHITE_BETTER)); break;
- case '\004': stringTextBuffer(tb, chessSymbol(EQUALITY)); break;
- case '\005': stringTextBuffer(tb, chessSymbol(UNCLEAR)); break;
- case '\006': stringTextBuffer(tb, chessSymbol(BLACK_BETTER)); break;
- case '\007': stringTextBuffer(tb, chessSymbol(BLACK_ADVANTAGE)); break;
- case '\010': stringTextBuffer(tb, chessSymbol(BLACK_WINNING)); break;
- case '\011': stringTextBuffer(tb, chessSymbol(NOVELTY)); break;
- case '\012': stringTextBuffer(tb, chessSymbol(COMPENSATION)); break;
- case '\013': stringTextBuffer(tb, chessSymbol(WITH_COUNTERPLAY)); break;
- case '\014': stringTextBuffer(tb, chessSymbol(WITH_INITIATIVE)); break;
- case '\015': stringTextBuffer(tb, chessSymbol(WITH_ATTACK)); break;
- case '\016': stringTextBuffer(tb, chessSymbol(TIME_TROUBLE)); break;
- case '\017': stringTextBuffer(tb, chessSymbol(ONLY_MOVE)); break;
- default: setError(ERR_UNKNOWN_POSITION_EVALUATION);
- }
-
- }
-
-
- /*------------------------------------------------------------
- * Functions
- *------------------------------------------------------------*/
-
- #define START_OF_COMMENT 0xff
- #define COMMENT_PADDING '\0'
-
-
- unsigned char *
- commentMove(Move m, unsigned char *s)
- { int l;
-
- if (*s != START_OF_COMMENT)
- { setError(ERR_FORMAT_ERROR_ANNOTATIONS);
- return s;
- }
- s++;
- m->moveEvaluation = *s++;
- if (*s == START_OF_COMMENT)
- return s;
- m->positionEvaluation = *s++;
- if (*s == START_OF_COMMENT)
- return s;
- m->extraEvaluation = *s++;
- if (*s == START_OF_COMMENT)
- return s;
-
- /* The current byte should perhaps contain the number of bytes
- * of (textual) comments remaining (Rolf Exner). At present
- * we ignore it and scan forward to the next START_OF_COMMENT
- * character and use that as a comment terminator.
- */
- if (*s == COMMENT_PADDING)
- l = 256;
- else
- l = (int) *s;
-
- s++;
-
- { unsigned char *t;
- int k = l;
-
- for (t=s; *s != START_OF_COMMENT && k; s++, k--)
- ;
- if (*s != START_OF_COMMENT)
- { setError(ERR_COMMENT_NOT_TERMINATED);
- *s = '\0';
- return s;
- }
- *s = '\0';
- m->commentLength = (s-t);
- m->comments = alloc(m->commentLength+1);
- strcpy((char *) m->comments, (char *) t);
- *s = START_OF_COMMENT;
- }
-
- return s;
-
- /* Code used when last byte contains number of characters in comment.
- m->commentLength = *s++;
- m->comments = alloc(m->commentLength+1);
- strncpy((char *) m->comments, (char *) s, m->commentLength);
- m->comments[m->commentLength] = '\0';
- s += m->commentLength;
-
- return s;
- */
- }
-
-
-